package com.advertisementsystem.Servie.Impl;

import com.advertisementsystem.Enum.AlertLevelEnum;
import com.advertisementsystem.Enum.AlertTypeEnum;
import com.advertisementsystem.Enum.SystemStatusEnum;
import com.advertisementsystem.Mapper.SysAlertMapper;
import com.advertisementsystem.Mapper.SystemMetricsMapper;
import com.advertisementsystem.Servie.SystemMonitorService;
import com.advertisementsystem.entity.SysAlert;
import com.advertisementsystem.entity.SysMetrics;
import com.advertisementsystem.response.PageResult;
import com.advertisementsystem.utils.RedisCache;
import com.advertisementsystem.vo.JvmMetrics;
import com.advertisementsystem.vo.SystemHealthReport;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.lang.management.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import com.sun.management.OperatingSystemMXBean;

@Service
@Slf4j
public class SystemMonitorServiceImpl implements SystemMonitorService {

    @Autowired
    private SystemMetricsMapper metricsMapper;

    @Autowired
    private SysAlertMapper alertMapper;

    @Autowired
    private RedisCache redisCache;

    private final OperatingSystemMXBean osBean = (OperatingSystemMXBean)
            ManagementFactory.getOperatingSystemMXBean();

    @Override
    public SysMetrics getCurrentMetrics() {
        try {
            // 1. 获取CPU使用率
            double cpuUsage = getCpuUsage();

            // 2. 获取内存使用率
            double memoryUsage = getMemoryUsage();

            // 3. 获取磁盘使用率
            double diskUsage = getDiskUsage();

            // 4. 获取JVM信息
            JvmMetrics jvmMetrics = getJvmMetrics();

            // 5. 构建指标对象
            SysMetrics metrics = SysMetrics.builder()
                    .cpuUsage(cpuUsage)
                    .memoryUsage(memoryUsage)
                    .diskUsage(diskUsage)  // 修正这里，之前写错了
                    .threadCount(jvmMetrics.getThreadCount())
                    .heapUsage(jvmMetrics.getHeapUsage())
                    .nonHeapUsage(jvmMetrics.getNonHeapUsage())
                    .timestamp(LocalDateTime.now())
                    .build();

            // 6. 保存指标
            metricsMapper.insert(metrics);

            // 7. 检查告警
            checkMetricsAlert(metrics);

            return metrics;
        } catch (Exception e) {
            log.error("获取系统指标失败", e);
            return null;
        }
    }
    private JvmMetrics getJvmMetrics() {
        try {
            // 1. 获取内存相关指标
            MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
            MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
            MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();

            // 2. 获取年轻代和老年代使用情况
            double youngGenUsage = 0.0;
            double oldGenUsage = 0.0;
            for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
                if (pool.getType() == MemoryType.HEAP) {
                    if (pool.getName().contains("Eden") || pool.getName().contains("Survivor")) {
                        MemoryUsage usage = pool.getUsage();
                        youngGenUsage = ((double) usage.getUsed() / usage.getMax()) * 100;
                    } else if (pool.getName().contains("Old") || pool.getName().contains("Tenured")) {
                        MemoryUsage usage = pool.getUsage();
                        oldGenUsage = ((double) usage.getUsed() / usage.getMax()) * 100;
                    }
                }
            }

            // 3. 获取类加载信息
            ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();

            // 4. 获取GC信息
            long gcCount = 0;
            long gcTime = 0;
            for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
                gcCount += gc.getCollectionCount();
                gcTime += gc.getCollectionTime();
            }  // 5. 获取运行时信息
            RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();

            // 6. 构建并返回JVM指标
            return JvmMetrics.builder()
                    .threadCount(Thread.activeCount())
                    .heapUsage(((double) heapMemoryUsage.getUsed() / heapMemoryUsage.getMax()) * 100)
                    .nonHeapUsage(((double) nonHeapMemoryUsage.getUsed() / nonHeapMemoryUsage.getCommitted()) * 100)
                    .uptime(runtimeMXBean.getUptime())
                    .youngGenUsage(youngGenUsage)
                    .oldGenUsage(oldGenUsage)
                    .loadedClassCount(classLoadingMXBean.getLoadedClassCount())
                    .gcCount(gcCount)
                    .gcTime(gcTime)
                    .build();

        } catch (Exception e) {
            log.error("获取JVM指标失败", e);
            return JvmMetrics.builder()
                    .threadCount(0)
                    .heapUsage(0.0)
                    .nonHeapUsage(0.0)
                    .uptime(0L)
                    .youngGenUsage(0.0)
                    .oldGenUsage(0.0)
                    .loadedClassCount(0)
                    .gcCount(0L)
                    .gcTime(0L)
                    .build();
        }
    }
    /**
     * 获取CPU使用率
     */
    @Override
    public double getCpuUsage() {
        try {
            return osBean.getCpuLoad() * 100;
        } catch (Exception e) {
            log.error("获取CPU使用率失败", e);
            return 0.0;
        }
    }

    /**
     * 获取内存使用率
     */
    @Override
    public double getMemoryUsage() {
        try {
            long totalMemory = osBean.getTotalMemorySize();
            long freeMemory = osBean.getFreeMemorySize();
            return ((double) (totalMemory - freeMemory) / totalMemory) * 100;
        } catch (Exception e) {
            log.error("获取内存使用率失败", e);
            return 0.0;
        }
    }

    /**
     * 获取磁盘使用率
     */
    @Override
    public double getDiskUsage() {
        try {
            File[] roots = File.listRoots();
            long totalSpace = 0;
            long usedSpace = 0;

            for (File root : roots) {
                totalSpace += root.getTotalSpace();
                usedSpace += (root.getTotalSpace() - root.getFreeSpace());
            }

            return totalSpace == 0 ? 0 : ((double) usedSpace / totalSpace) * 100.0;
        } catch (Exception e) {
            log.error("获取磁盘使用率失败", e);
            return 0.0;
        }
    }

    // ... getJvmMetrics() 方法保持不变 ...

    @Override
    public List<SysMetrics> getHistoryMetrics(LocalDateTime startTime, LocalDateTime endTime) {
        log.info("{}{}",endTime,startTime);
        try {
            log.info("{}",startTime);
            // return metricsMapper.selectByTimeRange(startTime, endTime);
            LambdaQueryWrapper<SysMetrics> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.between(SysMetrics::getTimestamp, startTime, endTime);
            List<SysMetrics> list = metricsMapper.selectList(queryWrapper);
            log.info("{}",list);
            return list;
        } catch (Exception e) {
            log.error("获取历史监控数据失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public SystemHealthReport generateHealthReport() {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            LocalDateTime startTime = endTime.minusHours(24);

            // 1. 获取24小时内的监控数据
            List<SysMetrics> metrics = getHistoryMetrics(startTime, endTime);

            log.info("{}",metrics);

            // 2. 计算CPU使用率统计
            DoubleSummaryStatistics cpuStats = metrics.stream()
                    .mapToDouble(SysMetrics::getCpuUsage)
                    .summaryStatistics();

            log.info("{}",cpuStats);
            // 3. 计算内存使用率统计
            DoubleSummaryStatistics memoryStats = metrics.stream()
                    .mapToDouble(SysMetrics::getMemoryUsage)
                    .summaryStatistics();

            log.info("{}",memoryStats);
            // 4. 计算磁盘使用率统计
            DoubleSummaryStatistics diskStats = metrics.stream()
                    .mapToDouble(SysMetrics::getCpuUsage)  // 修正这里，之前用错了方法
                    .summaryStatistics();

            log.info("{}",diskStats);
            // 5. 获取告警数量
            int alertCount = alertMapper.countRecentAlerts(startTime);

            // 6. 构建健康报告
            return SystemHealthReport.builder()
                    .reportTime(endTime)
                    .avgCpuUsage(cpuStats.getAverage())
                    .maxCpuUsage(cpuStats.getMax()>=0?cpuStats.getMax():0)
                    .avgMemoryUsage(memoryStats.getAverage())
                    .maxMemoryUsage(memoryStats.getMax()>=0?memoryStats.getMax():0)
                    .avgDiskUsage(diskStats.getAverage())  // 添加磁盘使用率
                    .alertCount(alertCount)
                    .status(determineSystemStatus(cpuStats.getAverage(),
                            memoryStats.getAverage(), alertCount))
                    .build();

        } catch (Exception e) {
            log.error("生成系统健康报告失败", e);
            return null;
        }
    }

    @Override
    public PageResult<SysAlert> getAlerts(Integer pageNum, Integer pageSize) {
        try {
            Page<SysAlert> page = new Page<>(pageNum, pageSize);
            IPage<SysAlert> alertPage = alertMapper.selectPage(page,
                    new LambdaQueryWrapper<SysAlert>()
                            .orderByDesc(SysAlert::getCreateTime));

            return new PageResult<>(alertPage);
        } catch (Exception e) {
            log.error("获取系统告警记录失败", e);
            return new PageResult<>();
        }
    }

    private void checkMetricsAlert(SysMetrics metrics) {
        // CPU告警检查
        if (metrics.getCpuUsage() > 80) {
            createAlert(AlertTypeEnum.PERFORMANCE, AlertLevelEnum.WARNING,
                    "CPU使用率过高: " + String.format("%.2f%%", metrics.getCpuUsage()),
                    metrics.getId());
        }

        // 内存告警检查
        if (metrics.getMemoryUsage() > 80) {
            createAlert(AlertTypeEnum.PERFORMANCE, AlertLevelEnum.WARNING,
                    "内存使用率过高: " + String.format("%.2f%%", metrics.getMemoryUsage()),
                    metrics.getId());
        }

        // 磁盘告警检查
        if (metrics.getDiskUsage() > 90) {
            createAlert(AlertTypeEnum.PERFORMANCE, AlertLevelEnum.WARNING,
                    "磁盘使用率过高: " + String.format("%.2f%%", metrics.getDiskUsage()),
                    metrics.getId());
        }
    }

    private void createAlert(AlertTypeEnum type, AlertLevelEnum level,
                             String message, Long metricsId) {
        SysAlert alert = SysAlert.builder()
                .type(type.getCode())
                .level(level.getCode())
                .message(message)
                .metricsId(metricsId)
                .createTime(LocalDateTime.now())
                .build();

        alertMapper.insert(alert);
    }

    private SystemStatusEnum determineSystemStatus(double avgCpu,
                                                   double avgMemory, int alertCount) {
        if (avgCpu > 80 || avgMemory > 80 || alertCount > 10) {
            return SystemStatusEnum.UNHEALTHY;
        } else if (avgCpu > 70 || avgMemory > 70 || alertCount > 5) {
            return SystemStatusEnum.WARNING;
        } else {
            return SystemStatusEnum.HEALTHY;
        }
    }
}